package com.zy.cat.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.zy.cat.common.annotation.RedisEvicts;
import com.zy.cat.common.annotation.RedisEvicts.RedisEvict;
import com.zy.cat.common.config.Configs;
import com.zy.cat.common.utils.AesEncryptUtils;
import com.zy.cat.common.utils.AppleAPI;
import com.zy.cat.common.utils.DateAPIUtils;
import com.zy.cat.common.utils.DrawProportionUtil;
import com.zy.cat.common.utils.ExtendMethod;
import com.zy.cat.common.utils.TJKUtils;
import com.zy.cat.dao.Dao;
import com.zy.cat.entity.app.CatUserFeedbackHistory;
import com.zy.cat.entity.app.repository.CatUserFeedbackHistoryRepository;
import com.zy.cat.entity.app.resp.CatUserFeedbackHistoryResp;
import com.zy.cat.entity.dev.CatDev5088InviteIncomeHistory;
import com.zy.cat.entity.dev.CatDevBeanVideoHistory;
import com.zy.cat.entity.dev.CatDevBeansConvertInfo;
import com.zy.cat.entity.dev.CatDevDeviceToken;
import com.zy.cat.entity.dev.CatDevHCInviteIncomeHistory;
import com.zy.cat.entity.dev.CatDevHCRemitInfo;
import com.zy.cat.entity.dev.CatDevRegisterIncomeHistory;
import com.zy.cat.entity.dev.CatDevRegisterInfo;
import com.zy.cat.entity.dev.CatDevRelation;
import com.zy.cat.entity.dev.CatDevRemitInfo;
import com.zy.cat.entity.dev.CatDevSignedBeansHistory;
import com.zy.cat.entity.dev.CatDevSignedHistory;
import com.zy.cat.entity.dev.CatDevUserInfo;
import com.zy.cat.entity.dev.CatDevUserTaskConfig;
import com.zy.cat.entity.dev.CatDevUserTaskRecord;
import com.zy.cat.entity.dev.CatDevWeInfo;
import com.zy.cat.entity.dev.CatDevZJInviteIncomeHistory;
import com.zy.cat.entity.dev.repository.CatDev5088InviteIncomeHistoryRepository;
import com.zy.cat.entity.dev.repository.CatDevBeanVideoHistoryRepository;
import com.zy.cat.entity.dev.repository.CatDevBeansConvertInfoRepository;
import com.zy.cat.entity.dev.repository.CatDevDeviceTokenRepository;
import com.zy.cat.entity.dev.repository.CatDevHCInviteIncomeHistoryRepository;
import com.zy.cat.entity.dev.repository.CatDevHCRemitInfoRepository;
import com.zy.cat.entity.dev.repository.CatDevNewAddOrderHistoryRepository;
import com.zy.cat.entity.dev.repository.CatDevReRedHistoryRepository;
import com.zy.cat.entity.dev.repository.CatDevRegisterIncomeHistoryRepository;
import com.zy.cat.entity.dev.repository.CatDevRegisterInfoRepository;
import com.zy.cat.entity.dev.repository.CatDevRelationRepository;
import com.zy.cat.entity.dev.repository.CatDevRemitInfoRepository;
import com.zy.cat.entity.dev.repository.CatDevUserInfoRepository;
import com.zy.cat.entity.dev.repository.CatDevUserTaskConfigRepository;
import com.zy.cat.entity.dev.repository.CatDevUserTaskRecordRepository;
import com.zy.cat.entity.dev.repository.CatDevZJInviteIncomeHistoryRepository;
import com.zy.cat.entity.dev.resp.CatDevBeanVideoHistoryResp;
import com.zy.cat.entity.dev.resp.CatDevCountResp;
import com.zy.cat.entity.dev.resp.CatDevHCInviteInfoResp;
import com.zy.cat.entity.dev.resp.CatDevOrderResp;
import com.zy.cat.entity.dev.resp.CatDevRemitInfoResp;
import com.zy.cat.entity.dev.resp.CatDevRemitRecordResp;
import com.zy.cat.entity.dev.resp.CatDevSignedHistoryResp;
import com.zy.cat.entity.dev.resp.CatDevUserInfoResp;
import com.zy.cat.entity.dev.resp.CatDevUserInfoResp.TLJInfo;
import com.zy.cat.entity.dev.resp.CatDevWelfareInfoResp;
import com.zy.cat.entity.dev.resp.CatDevWelfareInfoResp.UserTaskData;
import com.zy.cat.entity.dev.resp.CatDevZJInviteInfoResp;
import com.zy.cat.entity.game.repository.CatDevSignedBeansHistoryRepository;
import com.zy.cat.entity.game.repository.CatDevSignedHistoryRepository;
import com.zy.cat.entity.mall.resp.CatCashBonusHistoryResp;
import com.zy.cat.entity.mall.resp.CatCashBonusHistoryResp.CashBonus;
import com.zy.cat.entity.resp.Pages;
import com.zy.cat.entity.resp.ResultPage;
import com.zy.cat.entity.wx.WxUserInfo;
import com.zy.cat.entity.wx.repository.WxUserInfoRepository;
import com.zy.cat.service.AsyncService;
import com.zy.cat.service.CacheService;
import com.zy.cat.service.CatDevService;
import com.zy.cat.service.CatGameService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
/**
 * 
 * @info
 * @author Link
 * @date 2019-11-26 11:59
 */
public class CatDevServiceImpl implements CatDevService {
	@Autowired
	CacheService cacheService;

	@Autowired
	@Qualifier("redis17")
	RedisTemplate<String, Map<String, String>> redis17;

	@Autowired
	@Qualifier("redis15")
	RedisTemplate<String, Object> redis15;

	@Autowired
	AsyncService asyncService;

	@Autowired
	CatDevRelationRepository catDevRelationRepository;

	@Autowired
	CatDevUserInfoRepository catDevUserInfoRepository;

	@Autowired
	CatDevRegisterInfoRepository catDevRegisterInfoRepository;

	@Autowired
	CatDevRemitInfoRepository catDevRemitInfoRepository;

	@Autowired
	CatDevUserTaskConfigRepository catDevUserTaskConfigRepository;

	@Autowired
	CatUserFeedbackHistoryRepository userFeedbackHistoryRepository;

	@Autowired
	CatDevUserTaskRecordRepository newUserTaskRecordRepository;

	@Autowired
	Dao<CatDevUserInfo> catDao;

	@Autowired
	CatDevHCRemitInfoRepository catDevHCRemitInfoRepository;

	@Autowired
	CatDevDeviceTokenRepository catDevDeviceTokenRepository;

	@Autowired
	Dao<CatDevHCInviteInfoResp> hcInviteInfoRespDao;

	@Autowired
	Dao<CatDevRemitInfo> remitInfoDao;

	@Autowired
	Dao<CatDevRemitRecordResp> remitDao;

	@Autowired
	Dao<CatDevRemitRecordResp> catDevRemitInfoRespDao;

	@Autowired
	Dao<CatDevSignedHistoryResp> signedHistoryRespDao;

	@Autowired
	Dao<CatDevSignedBeansHistory> signedBeansHistoryDao;

	@Autowired
	Dao<CashBonus> cashBonusDao;

	@Autowired
	Dao<CatDevUserInfoResp> catDevUserInfoRespDao;

	@Autowired
	Dao<CatDevUserTaskRecord> userTaskRecordDao;

	@Autowired
	Dao<Long> longDao;

	@Autowired
	Dao<Integer> intDao;

	@Autowired
	Dao<TLJInfo> tljDao;

	@Autowired
	CatDevSignedHistoryRepository signedHistoryRepository;

	@Autowired
	CatDevNewAddOrderHistoryRepository newAddOrderHistoryRepository;

	@Autowired
	CatDevSignedBeansHistoryRepository signedBeansHistoryRepository;

	@Autowired
	CatDevBeansConvertInfoRepository beansConvertInfoRepository;

	@Autowired
	CatDevRegisterIncomeHistoryRepository catDevRegisterIncomeHistoryRepository;

	@Autowired
	CatDevHCInviteIncomeHistoryRepository catDevHCInviteIncomeHistoryRepository;

	@Autowired
	CatDevZJInviteIncomeHistoryRepository catDevZJInviteIncomeHistoryRepository;

	@Autowired
	CatDev5088InviteIncomeHistoryRepository catDev5088InviteIncomeHistoryRepository;

	@Autowired
	CatDevBeanVideoHistoryRepository beanVideoHistoryRepository;

	@Autowired
	private CatDevReRedHistoryRepository catDevReRedHistoryRepository;

	@Autowired
	WxUserInfoRepository wxUserInfoRepository;

	@Autowired
	CatGameService catGameService;

	@Autowired
	@Qualifier("redis0")
	RedisTemplate<String, Object> redis0;

	@Autowired
	@Qualifier("redis1")
	RedisTemplate<String, Object> redis1;

	@Autowired
	Configs configs;

	private final String REMIT_WX_KEY = "CAT_USER_WX_REMIT_LIST";

	private final String REMIT_ZFB_KEY = "CAT_USER_ZFB_REMIT_LIST";

	private final String USER_OPEN_NUM = "USER_OPEN_NUM";

	private final String USER_POPUP_LIST_KEY = "USER_POPUP_LIST";

	/**
	 * 每日弹窗记录,只缓存一天，index：0.首页200弹窗、1.刮刮卡200弹窗、2.神奇便利店200弹窗
	 */
	private final String POPUP_RECORD_DAILY_KEY = "CAT_POPUP_RECORD_DAILY_KEY";
	// 用户访问info接口情况，只缓存一天
	private final String USER_REQUEST_INFO_RECORD_KEY = "USER_REQUEST_INFO_RECORD";

	@Override
	public CatDevUserInfoResp login(String userid, int rtype, CatDevWeInfo weInfo, String vscode, String brand,
			String model, String cid, String imei, String imsi, Integer pindex) {
		String unionid = weInfo.getUnionid();
		String openid = weInfo.getOpenid();
		String nikename = weInfo.getNickname();
		String icon = weInfo.getHeadimgurl();
		int sex = weInfo.getSex();
		/* 查看是否存在 */
		boolean isOk = false;
		/* 是否为老用户 */
		boolean isOldUser = false;
		/* 打开APP次数 */
		Integer openNum = 0;
		// 返回提示信息
		String msg = null;

//		CatDevUserInfo zdev = null;
//		if(rtype==1&&StringUtils.isNotBlank(userid)) {
//			zdev = getCatDevUserInfoByUserid(userid);
//			
//			CatDevUserInfo cdev = getCatDevUserInfoByUnionid(unionid);
//			
//			if(cdev==null) {
//				zdev=null;
//			}
//		}else {
//			zdev=getCatDevUserInfoByUnionid(unionid);
//		}
		CatDevUserInfo zdev = getCatDevUserInfoByUnionid(unionid);
		CatDevUserInfo udev = getCatDevUserInfoByUserid(userid);
		if (zdev == null) {
			// 判断此用户是否有已注销的账号
			List<CatDevUserInfo> list = catDevUserInfoRepository.findByUnionid(unionid);
			List<CatDevUserInfo> clist = null;
			if (!StringUtils.isEmpty(userid)) {
				clist = catDevUserInfoRepository.findByUserid(userid);
			}
//			if(rtype==1&&StringUtils.isNotBlank(userid)) {
//				list = catDevUserInfoRepository.findByUserid(userid);
//			}else {
//				list = catDevUserInfoRepository.findByUnionid(unionid);
//			}
			// 如果已存在账号，则新建的账号直接为老用户
			if ((list != null && list.size() > 0) || (clist != null && clist.size() > 0)) {
				isOldUser = true;
			}
			/* 生成用户PID */
			long pid_1 = RandomUtils.nextLong(1111111111, 9999999999L);
			CatDevUserInfo insertDev = getCatDevUserInfoByPid(pid_1 + "");
			int count = 20;
			/* 用户PID存在重新生成 */
			while (insertDev != null && count > 0) {
				pid_1 = RandomUtils.nextLong(1111111111, 9999999999L);
				insertDev = getCatDevUserInfoByPid(pid_1 + "");
				count--;
			}

			CatDevUserInfo insertDevs = new CatDevUserInfo(pid_1 + "", unionid, openid,
					AesEncryptUtils.encrypt(nikename), icon, sex, isOldUser == true ? 1 : 0);
			if (StringUtils.isNotBlank(userid) && userid.length() > 20 && udev == null) {
				insertDevs.setUserid(userid);
			}
			log.info("insertDevs--->" + JSON.toJSONString(insertDevs));
			/* 用户注册 */
			if (insertDev == null && catDao.insert(insertDevs)) {
				/* 存储注册信息 */
				if (catDevRegisterInfoRepository.saveAndFlush(new CatDevRegisterInfo(pid_1 + "", brand, model, vscode,
						cid, imei, imsi, rtype, TJKUtils.DateTime(), "账户注册")) != null) {
					// 如果为老用户则不再设置新用户奖励
					if (!isOldUser) {
						CatDevRegisterIncomeHistory registerBeansIncome=null;
						/*680现金豆奖励*/
						if(cid.equals("ym-xiaomi")) {
							registerBeansIncome=new CatDevRegisterIncomeHistory(pid_1 + "", 0,
									680, 1, TJKUtils.DateTime(), TJKUtils.DateTime(), "注册奖励");
						}else {
							/*3000现金豆奖励*/
							registerBeansIncome= new CatDevRegisterIncomeHistory(pid_1 + "", 0,
									3000, 1, TJKUtils.DateTime(), TJKUtils.DateTime(), "注册奖励");
						}
						catDevRegisterIncomeHistoryRepository.saveAndFlush(registerBeansIncome);
					}
					isOk = true;
				}

				// 设置新用户任务记录
				insertNewUserTask(pid_1 + "");
			}
		} else {

			/* 绑定苹果账户ID */
			if (StringUtils.isNotBlank(userid) && userid.length() > 20 && udev == null
					&& (zdev.getUserid() == null || zdev.getUserid().length() < 20)) {
				zdev.setUserid(userid);
				catDevUserInfoRepository.saveAndFlush(zdev);
			}

			/* 异步更新用户微信信息 :目前仅更新openID信息 */
			updateUserWxInfo(zdev, unionid, openid);
			// 获取用户打开应用次数
			openNum = (Integer) redis15.opsForHash().get(USER_OPEN_NUM, zdev.getPid());
			if (openNum == null) {
				// 判断签到次数，一天为一次
				Integer count = signedHistoryRepository.countByUnionid(zdev.getUnionid());
				openNum = count;
			}
		}
		CatDevUserInfoResp result = cacheService.getCatDevUserLoginInfo(unionid);
		if (result == null) {
			/* 延迟再次获取数据库中用户的注册信息 */
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
			}
			result = cacheService.getCatDevUserLoginInfo(unionid);
		}

		if (result != null) {
			CatDevUserInfoResp resultIncome = cacheService.getCatDevUserLoginInfo(unionid);
			if (resultIncome != null) {
				result.setArpt(resultIncome.getArpt());
				result.setAbeans(resultIncome.getAbeans());
				result.setRpt(resultIncome.getRpt());
				result.setBeans(resultIncome.getBeans());
				result.setJrpt(resultIncome.getJrpt());
				result.setJbeans(resultIncome.getJbeans());
			}

			if (isOk && !isOldUser) {
				CatDevRelation inviteInfo = catDevRelationRepository.findInviteUser(unionid,
						LocalDate.now().toString());
				/* 被邀请注册的用户 */
				if (inviteInfo != null) {
					inviteInfo.setPid(result.getPid());
					inviteInfo.setYstatus(1);
					inviteInfo.setLtime(TJKUtils.DateTime());
					if (inviteInfo.getYtype() == 2) {
						// TODO 5088邀请成功
						if (catDevRelationRepository.saveAndFlush(inviteInfo) != null) {
							CatDev5088InviteIncomeHistory inviteIncome = null;
							int iindex = catDev5088InviteIncomeHistoryRepository.getMaxIndex(inviteInfo.getYpid());
							iindex++;
							long income = 900;
							if (iindex >= 101) {
								income = 1300;
							} else if (iindex >= 21) {
								income = 1200;
							} else if (iindex >= 4) {
								income = 1100;
							} else if (iindex >= 2) {
								income = 1000;
							}
							inviteIncome = new CatDev5088InviteIncomeHistory(result.getPid(), inviteInfo.getYpid(),
									income, 3000, iindex, 0, TJKUtils.DateTime(), TJKUtils.DateTime(), "-");
							catDev5088InviteIncomeHistoryRepository.saveAndFlush(inviteIncome);
						}
					} else {
						/* 判断用户信息是否已经注册过 */
						List<CatDevRegisterInfo> ydev = catDevRegisterInfoRepository.findByImeiOrImsi(imei, imsi);
						if (ydev == null || ydev.isEmpty()) {
							inviteInfo.setJstatus(1);
						}
						if (catDevRelationRepository.saveAndFlush(inviteInfo) != null) {
							/* 直接邀请：存储第一天登录奖励3元，并记录七天有效期内数据 */
							if (inviteInfo.getYtype() == 0) {
								// 查询今日已邀请人数
								Integer todayInviteNum = intDao.selectOne(
										new CatDevZJInviteInfoResp(inviteInfo.getYpid()), "getTodayInviteCount");
								int todayMaxNum = (LocalDate.now().getDayOfMonth() + Integer
										.parseInt(inviteInfo.getYpid().substring(inviteInfo.getYpid().length() - 2)))
										% 4;
								if (todayInviteNum > todayMaxNum) {
									msg = "邀请无效，今日邀请人数已达上限";
								}
								// 判断推广者邀请的数量是否超过限制，最大100人
								int count = catDevRelationRepository.countByYpidAndYtypeAndYstatus(inviteInfo.getYpid(),
										0, 1);
								// 如果该邀请已超过100则增加提示信息
								if (count > 100) {
									msg = "邀请无效，邀请人邀请人数已达上限";
								}
								CatDevZJInviteIncomeHistory zjInvite = catDevZJInviteIncomeHistoryRepository
										.findByPidAndYidAndIstatusAndItype(result.getPid(), inviteInfo.getYpid(), 1, 1);
								if (zjInvite == null && count <= 100 && todayInviteNum <= todayMaxNum) {
									// 查询最大邀请index,增加1
									Integer index = intDao.selectOne(new CatDevZJInviteInfoResp(inviteInfo.getYpid()),
											"getMaxIndex");
									int iindex = index == null ? 0 : index + 1;
									CatDevZJInviteIncomeHistory zjInvite_day1 = new CatDevZJInviteIncomeHistory(
											result.getPid(), inviteInfo.getYpid(), 1, 300, iindex, 0,
											LocalDate.now().toString(), LocalDate.now().plusDays(6).toString(),
											TJKUtils.DateTime(), TJKUtils.DateTime(), "");
									CatDevZJInviteIncomeHistory zjInvite_day2 = new CatDevZJInviteIncomeHistory(
											result.getPid(), inviteInfo.getYpid(), 2, 100, zjInvite_day1.getIindex(), 0,
											zjInvite_day1.getStime(), zjInvite_day1.getEtime(),
											zjInvite_day1.getCtime(), zjInvite_day1.getLtime(), "");
									CatDevZJInviteIncomeHistory zjInvite_day3 = new CatDevZJInviteIncomeHistory(
											result.getPid(), inviteInfo.getYpid(), 3, 100, zjInvite_day1.getIindex(), 0,
											zjInvite_day1.getStime(), zjInvite_day1.getEtime(),
											zjInvite_day1.getCtime(), zjInvite_day1.getLtime(), "");
									CatDevZJInviteIncomeHistory zjInvite_day4 = new CatDevZJInviteIncomeHistory(
											result.getPid(), inviteInfo.getYpid(), 4, 500, zjInvite_day1.getIindex(), 0,
											zjInvite_day1.getStime(), zjInvite_day1.getEtime(),
											zjInvite_day1.getCtime(),

											zjInvite_day1.getLtime(), "");
									CatDevZJInviteIncomeHistory[] arrays = { zjInvite_day1, zjInvite_day2,
											zjInvite_day3, zjInvite_day4 };
									catDevZJInviteIncomeHistoryRepository.saveAll(Arrays.asList(arrays));
									catDevZJInviteIncomeHistoryRepository.flush();

									/* 邀请好友注册成功,记录邀请人的通知缓存中并通知 */
//								asyncService.updateCatDevInviteAwardRecord(inviteInfo.getYpid(), 1,zjInvite_day1.getIncome(),result.getNikename(),zjInvite_day1.getItype());

//								zjInvite=new CatDevZJInviteIncomeHistory(result.getPid(), inviteInfo.getYpid(), TJKUtils.DateTime(), TJKUtils.DateTime());
//								zjInvite.setItype(1);
//								zjInvite.setIncome(300);
//								zjInvite.setIindex(1);
//								zjInvite.setStime(LocalDate.now().toString());
//								zjInvite.setEtime(LocalDate.now().plusDays(6).toString());
//								catDevZJInviteIncomeHistoryRepository.saveAndFlush(zjInvite);
								}
							} else if (inviteInfo.getYtype() == 1) {
								String stime = TJKUtils.DateTime();
								String ctime = stime, ltime = stime;
								String etime = TJKUtils.parse2LocalDateTime(stime).plusDays(1)
										.format(DateAPIUtils.FORMATTER_YYYYMMDDHHMMSS);

								CatDevHCInviteIncomeHistory inviteIncomeInfo = null;
								List<CatDevHCInviteIncomeHistory> inviteList = catDevHCInviteIncomeHistoryRepository
										.getInviteInfos(inviteInfo.getYpid());
								if (inviteList == null || inviteList.isEmpty()) {
									/* 用户未开始下一轮，不做处理 */
								} else {
									stime = inviteList.get(0).getStime();
									etime = inviteList.get(0).getEtime();
									ctime = TJKUtils.DateTime();
									ltime = ctime;

									/* 计算总金额 */
									long yincome = 0;

									/* 邀请成功人数 */
									long ycount = 0;

									String aid = null;
									for (CatDevHCInviteIncomeHistory catDevHCInviteIncomeHistory : inviteList) {
										if (catDevHCInviteIncomeHistory.getYtype() == 3) {
											ycount++;
										}
										yincome += catDevHCInviteIncomeHistory.getIncome();
										aid = catDevHCInviteIncomeHistory.getAid();
									}
									long rincome = 1000 - yincome;
									/* 判断加上本次2人邀请奖励是否完成，完成补充金额到达提现金额10元 */
									if (ycount + 1 >= 2) {
										inviteIncomeInfo = new CatDevHCInviteIncomeHistory(inviteInfo.getYpid(), stime,
												etime, rincome, 3, inviteInfo.getUnionid(), 1, 0, ctime, ltime, "-",
												aid);
										if (catDevHCInviteIncomeHistoryRepository
												.saveAndFlush(inviteIncomeInfo) != null) {
											catDevHCInviteIncomeHistoryRepository.updInviteInfos(inviteInfo.getYpid());
										}
									} else {
										rincome = rincome / 2;
										inviteIncomeInfo = new CatDevHCInviteIncomeHistory(inviteInfo.getYpid(), stime,
												etime, rincome, 3, inviteInfo.getUnionid(), 1, 0, ctime, ltime, "-",
												aid);
										catDevHCInviteIncomeHistoryRepository.saveAndFlush(inviteIncomeInfo);
									}

									/* 邀请好友助力拆红包成功,记录邀请人的通知缓存中 */
									asyncService.updateCatDevInviteAwardRecord(inviteInfo.getYpid(), 1, rincome,
											result.getNikename(), 0);
								}
							}
						}
					}
				}
//				CatDevRelation insertRelation = null;
//				if (StringUtils.isBlank(pid) || pid.length() < 10) {
//					insertRelation = new CatDevRelation(result.getPid() + "_1111111111", result.getPid(), "1111111111",
//							"2222222222", ystatus, TJKUtils.DateTime(), "--");
//				} else {
//					CatDevRelation rdev = catDevRelationRepository.findByPid(pid);
//					if (rdev != null) {
//						insertRelation = new CatDevRelation(result.getPid() + "_" + pid, result.getPid(), rdev.getPid(),
//								rdev.getYpid(), ystatus, TJKUtils.DateTime(), "--");
//					} else {
//						insertRelation = new CatDevRelation(result.getPid() + "_1111111111", result.getPid(),
//								"1111111111", "2222222222", ystatus, TJKUtils.DateTime(), "--");
//					}
//				}
//				catDevRelationRepository.saveAndFlush(insertRelation);
			} else {
				updateInviteInfo(rtype, unionid, result);

			}
			String utoken = AesEncryptUtils.encryptBySalt(result.getPid());
			redis0.opsForHash().put("CAT_DEV_LOGIN_TOKEN", result.getPid(), utoken);
			result.setUtoken(utoken);

			// 查询现金豆数量与现金红包
			CatDevUserInfoResp beansData = cacheService.getCatDevBeansData(result.getPid());
			result.setBeans(beansData.getBeans());
			result.setAbeans(beansData.getAbeans());
			result.setJbeans(beansData.getJbeans());
			result.setBeans(cacheService.getCatDevLastBeans(result.getPid()));
			result.setRpt(cacheService.getCatDevLastRMB(result.getPid()));

			// 查询正在入账金额
			Long amount = longDao.selectOne(new CatDevOrderResp(result.getPid(), 0, 10), "getOrderAmountByStatus");
			result.setRcode(amount);

			// 1.1.6版本查询淘礼金信息
			TLJInfo tljInfo = tljDao.selectOne(new CatDevUserInfo(result.getPid()), "getTljInfo");
			if (tljInfo != null) {
				result.setTljInfo(tljInfo);
			}

			CatDevUserInfoResp.CashBalanceInfo balanceInfo = cacheService.getUserBalance(result.getPid());
			balanceInfo.setReadyRebate(amount);
			result.setBalanceInfo(balanceInfo);

			// 签到信息
			// 查询连续签到天数
			CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(result.getPid());
			result.setSigns(historyResp.getSigns());
			String endDate = historyResp.getEndDate();
			// 如果最后签到的日期不是为今日,则新建今天的签到记录
			if (endDate == null || !endDate.equals(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD))) {
				// 今天未签到
				result.setSigned(0);
			} else {
				// 如果连续签到天数为0,则说明今日已拒签
				if (historyResp.getSigns() == 0) {
					result.setSigned(-1);
				} else {
					result.setSigned(1);
				}
			}
			// 获取当前签到红包是否领取
			result.setSignedpcks(getSignedReceiveStatus(result.getPid()) == true ? 1 : 0);
			result.setNikename(AesEncryptUtils.decrypt(result.getNikename()));

			// 设置奖品碎片信息
			result.setPrizeInfoResp(catGameService.getCVSPrizeInfoResp(result.getPid()));
			// 设置订单状态
			Integer orderNumber = cacheService.getUserOrderNumber(result.getPid());
			CatDevCountResp countResp = new CatDevCountResp();
			// 设置订单数量
			countResp.setOrderRebateCount(orderNumber == null ? 0 : orderNumber);
			result.setOrderStatus(orderNumber == null ? 0 : 1);
			// 获取是否下单过大额券
			Integer number = cacheService.getUserDaEOrderNumber(result.getPid());
			result.setSupercoupon(number == null || number == 0 ? 0 : 1);
			int addOrderNum = newAddOrderHistoryRepository.countByPid(result.getPid());
			// 获取用户新增订单数量
			countResp.setAddOrderCount(addOrderNum);
			// 获取用户待提升返利概率订单数量
			int promotedOrderCount = cacheService.getNotPromotedOrderCount(result.getPid());
			countResp.setNotPromotedCount(promotedOrderCount);
			result.setCountResp(countResp);

			if (addOrderNum > 0) {
				// 设置响应数据成功,清除通知新增订单数据
				asyncService.deleteNewAddOrderHistory(result.getPid());
				// 更新任务状态
				userTaskRecordDao.update(new CatDevUserTaskRecord(result.getPid(), 2), "updateTaskStatus");
			}
			// 设置广告开关状态
			result.setAdStatus(cacheService.getCatAppAdStatus(rtype, cid, vscode));

			if (isOldUser) {
				result.setMsg("该账号为老用户");
			}
			if (pindex != -1) {
				// 记录打开次数
				openNum++;
				saveUserOpenNum(result.getPid(), openNum);
			}
			// 判断是否为新用户
			if (openNum > 4) {
				result.setUtype(1);
			}
			// 判断弹窗
			result.setPopupId(getPopupId(pindex, openNum, result.getPid()));
			// 判断用户是否满足新人提现条件
			result.setNewUserRemit(isAbleNewUserRemit(result.getPid()) ? 1 : 0);

			// 弹窗逻辑去除，新老用户均不弹窗
			result.setPopupId(0);

			// 查询是否有反馈回复信息
			if (userFeedbackHistoryRepository.countByUserIdAndStatus(result.getPid(), 2) > 0) {
				result.setIsFeedbackMsg(1);
			}
		} else {
			log.error("query user info fail, unionid :" + unionid);
		}
		return result;
	}

	/**
	 * 注册新用户新人任务记录
	 * 
	 * @author lipengchao
	 * @date 2020-05-07 06:23:34
	 * @param pid
	 */
	private void insertNewUserTask(String pid) {
		// 设置对应奖励的现金豆数
		List<CatDevUserTaskConfig> taskConfigList = catDevUserTaskConfigRepository.findByTaskAttributeOrderByTypeId(0);
		List<CatDevUserTaskRecord> list = taskConfigList.stream().map(config -> {
			return new CatDevUserTaskRecord(config.getTypeId(), pid, config.getBeanNum(), TJKUtils.DateTime(), 0);
		}).collect(Collectors.toList());
		// 批量插入进行
		newUserTaskRecordRepository.saveAll(list);
		newUserTaskRecordRepository.flush();
	}

	/**
	 * 检查更新邀请信息
	 * 
	 * @date 2020-03-18 10:50:40
	 * @param unionid
	 * @param result
	 */
	private void updateInviteInfo(int rtype, String unionid, CatDevUserInfoResp result) {
		// 判断是否已完成新人任务,完成新人任务后才可记录邀请任务信息
		if (cacheService.getCatDevBeansByGame(result.getPid()) >= DrawProportionUtil.NEW_USER_TASK_BAENS_NUM) {

			// 判断是否已为正常用户,如果为非正常用户则直接返回
			if (!cacheService.isNormalCatUser(rtype, result.getPid(), 0)) {
				return;
			}

			// 判断邀请类型
			CatDevRelation inviteInfo = catDevRelationRepository.findInviteUser(unionid, LocalDate.now().toString());

			if (inviteInfo != null) {
				// 5088邀请是否满足条件
				if (inviteInfo.getYtype() == 2) {
					// TODO 5088邀请是否满足条件-task更新
				}
				// 如果为直接邀请进来,则判断是否邀请的两个新用户都满足提现条件
				else if (inviteInfo.getYtype() == 1) {
					// 更新互拆提现
					updateHCRemit(inviteInfo.getYpid(), unionid);
				} else if (false && inviteInfo.getYtype() == 3) {

				} else {
					/* 记录直接邀请用户第几次登录 */
					// 判断今天是否已领取
					CatDevZJInviteIncomeHistory zjInvite = catDevZJInviteIncomeHistoryRepository
							.findZJInviteLast(result.getPid());
					// 今天未领取
					if (zjInvite == null) {
						CatDevZJInviteIncomeHistory taskHistory = catDevZJInviteIncomeHistoryRepository
								.findZJInviteOpenTaskHistory(result.getPid());
						if (taskHistory != null) {
							taskHistory.setLtime(TJKUtils.DateTime());
							taskHistory.setIstatus(1);
							catDevZJInviteIncomeHistoryRepository.saveAndFlush(taskHistory);
							/* 邀请好友任务完成,记录邀请人的通知缓存中 */
							asyncService.updateCatDevInviteAwardRecord(taskHistory.getYid(), 1, taskHistory.getIncome(),
									result.getNikename(), taskHistory.getItype());
						}
					}

					// 查询未完成的订单任务
					CatDevZJInviteIncomeHistory history = catDevZJInviteIncomeHistoryRepository
							.findByPidAndItypeAndIstatus(result.getPid(), 4, 0);
					if (history != null) {
						// 查询用户已完成订单数量
						Integer count = intDao.selectOne(new CatDevOrderResp(result.getPid(), 1, 10),
								"getOrderCountByPid");
						if (count > 0) {
							history.setLtime(TJKUtils.DateTime());
							history.setIstatus(1);
							catDevZJInviteIncomeHistoryRepository.saveAndFlush(history);
							/* 邀请好友任务完成,记录邀请人的通知缓存中 */
							asyncService.updateCatDevInviteAwardRecord(history.getYid(), 1, history.getIncome(),
									result.getNikename(), history.getItype());
						}
					}
				}
			}
		}
	}

	/**
	 * 更新用户注册渠道号
	 * 
	 * @param registerInfo
	 * @param cid
	 */
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_REGISTER_INFO", hashKeys = {
					"+#registerInfo.pid" }) })
	private void updateUserRegisterCid(CatDevRegisterInfo registerInfo, String cid) {
		registerInfo.setCid(cid);
		catDevRegisterInfoRepository.saveAndFlush(registerInfo);
	}

	/**
	 * 更新用户微信信息
	 */
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	private String updateUserWxInfo(CatDevUserInfo zdev, String unionid, String openid) {
		asyncService.updateCatDevWeInfo(unionid, openid);
		return "更新成功";
	}

	/**
	 * 获取弹窗ID
	 * 
	 * @date 2019-12-10 10:34:55
	 * @param pageIndex 0.首页、1.个人中心
	 * @param openNum
	 * @param pid
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private int getPopupId(int pageIndex, int openNum, String pid) {
		int popId = 0;
		// 是否展示
		Object object = redis15.opsForHash().get(POPUP_RECORD_DAILY_KEY, pid);
		List<Integer> showPopupList = null;
		Integer isShow = null;
		if (object instanceof List) {
			showPopupList = (List<Integer>) object;
		} else {
			isShow = (Integer) object;
		}
		if (showPopupList == null || showPopupList.size() < 1) {
			showPopupList = new ArrayList<>(3);
			showPopupList.addAll(Arrays.asList(null, null, null));
		}
		isShow = showPopupList.get(0) == null ? isShow : showPopupList.get(0);
		Integer temp = isShow;
		if (isShow == null) {
			// 若新用户弹窗流程未走完，将每日弹窗全部不展示(设置为不弹出)
			// value: -1.不展示、0.未展示、1.已展示
			isShow = openNum <= 4 ? -1 : 0;
		}
		// 如果打开次数大于4次，则不走新用户弹窗流程
		if (openNum > 4) {
			// 当打开次数大于四次小于6次时，将对应的数据清除
			if (openNum > 4 && openNum < 6) {
				redis15.opsForHash().delete(USER_POPUP_LIST_KEY, pid);
			}
			// 首页位置,判断是否有弹窗
			if (pageIndex == 0) {
				// 判断今日首页200现金豆是否已经弹框,如果未弹框则进行弹窗
				if (isShow == 0) {
					popId = 7;
					// 记录为已展示弹窗
					isShow = 1;
				}
			} else if (pageIndex == 1) {
				// 个人中心位置
				if (isShow == 0 || isShow == 1) {
					// 个人中心新用户流程执行完，客户端控制弹窗
					popId = 8;
				}
			}
		} else {
			Map<String, Object> map = (Map<String, Object>) redis15.opsForHash().get(USER_POPUP_LIST_KEY, pid);
			// 如果等于空，则新建
			if (map == null) {
				// key为弹窗ID,值表示是否已弹
				map = new HashMap<>();
				for (int i = 0; i < 6; i++) {
					map.put("" + (i + 1), 0);
				}
			}

			// 首页位置
			if (pageIndex == 0) {
				if (openNum != 4) {
					// 如果本次打开还未弹出此窗则进行弹窗
					if ((Integer) map.get(openNum + "") == 0) {
						map.put(openNum + "", 1);
						popId = openNum;
					}
				}
			} else if (pageIndex == 1) {
				// 个人中心位置
				if (openNum != 1) {
					// 如果本次打开还未弹出此窗则进行弹窗
					if ((Integer) map.get((openNum + 2) + "") == 0) {
						map.put((openNum + 2) + "", 1);
						popId = openNum + 2;
					}
				}
			}
			if (popId != 0) {
				redis15.opsForHash().put(USER_POPUP_LIST_KEY, pid, map);
			}
		}
		showPopupList.set(0, isShow);
		// 如果不存在
		if (!redis15.hasKey(POPUP_RECORD_DAILY_KEY)) {
			redis15.opsForHash().put(POPUP_RECORD_DAILY_KEY, pid, showPopupList);
			// 设置过期时间为一天
			Date date = Date.from(LocalDateTime.now().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant());
			redis15.expireAt(POPUP_RECORD_DAILY_KEY, date);
		} else if (!isShow.equals(temp)) {
			// 数据发生变化是进行更新
			redis15.opsForHash().put(POPUP_RECORD_DAILY_KEY, pid, showPopupList);
		}
		return popId;
	}

	/**
	 * 保存新用户打开次数
	 * 
	 * @param pid
	 * @param openNum
	 */
	private void saveUserOpenNum(String pid, int openNum) {
		redis15.opsForHash().put(USER_OPEN_NUM, pid, openNum);
	}

	/**
	 * 更新互拆提现
	 * 
	 * @date 2019-12-10 10:34:55
	 * @param ypid
	 * @param unionid
	 */
	private void updateHCRemit(String ypid, String unionid) {
		// 判断是否满足提现的条件
		// 判断是否已完成新人任务
		CatDevHCInviteInfoResp infoResp = new CatDevHCInviteInfoResp(ypid);
		infoResp.setYunionid(unionid);
		List<CatDevHCInviteInfoResp> list = hcInviteInfoRespDao.list(infoResp, "getHCInviteNewUserInfo");
		if (list == null || list.size() < 2) {
			return;
		}
		// 遍历查询是否都已完成新人任务
		boolean isComplete = true;
		for (CatDevHCInviteInfoResp resp : list) {
			if (cacheService.getCatDevBeansByGame(resp.getPid()) < DrawProportionUtil.NEW_USER_TASK_BAENS_NUM) {
				isComplete = false;
				break;
			}
		}
		// 如果完成则直接进行打款操作
		if (isComplete) {
			CatDevHCRemitInfo remit = catDevHCRemitInfoRepository.findByPidAndAidAndTstatus(ypid, list.get(0).getAid(),
					0);
			if (remit == null) {
				return;
			} else if (TJKUtils.parse2LocalDateTime("2020-02-10 00:00:00")
					.isAfter(TJKUtils.parse2LocalDateTime(remit.getCtime()))) {
				// 判断是否是以前提现的用户，如果是以前互拆提现的用户则不作时间限制
			} else if (TJKUtils.parse2LocalDateTime(remit.getCtime()).plusDays(7).isBefore(LocalDateTime.now())) {
				// 已过期
				remit.setTstatus(-1);
				remit.setDstatus(-1);
				remit.setTinfo("所邀请的用户未在7日内完成新人任务");
				catDevHCRemitInfoRepository.saveAndFlush(remit);
				return;
			}
			CatDevRemitRecordResp remitRecordResp = remit(0, 1, ypid, remit.getQtype(), 2, remit.getZaccount(),
					remit.getZrealname(), remit.getDmoney());
			remit.setOid(remitRecordResp.getOid());
			catDevHCRemitInfoRepository.saveAndFlush(remit);
		}
	}

	/**
	 * 
	 * @info 根据登录天数、邀请者位数获取返利金
	 * @author Link
	 * @date 2019-11-28 20:11
	 * @param index
	 * @param times
	 * @return
	 */
	private long getDayIncome(int index, long times) {
		long result = 0;
		if (times == 2) {
			if (index <= 3) {
				result = 100;
			} else {
				result = 200;
			}
		} else if (times == 3) {
			if (index == 1) {
				result = 100;
			} else if (index <= 20) {
				result = 200;
			} else if (index <= 100) {
				result = 300;
			} else {
				result = 400;
			}
		}
		return result;
	}

	@Override
	public CatDevUserInfoResp info(int rtype, CatDevUserInfo zdev, Integer pindex, String vscode, String cid) {
		CatDevUserInfoResp result = cacheService.getCatDevUserLoginInfo(zdev.getUnionid());
		if (result != null) {
			// 判断是否为当天第一次进入,每天会更新一次
			Integer reqCount = (Integer) redis15.opsForHash().get(USER_REQUEST_INFO_RECORD_KEY, zdev.getPid());
			if (reqCount == null) {
				reqCount = 1;
				if (!redis15.hasKey(USER_REQUEST_INFO_RECORD_KEY)) {
					redis15.opsForHash().put(USER_REQUEST_INFO_RECORD_KEY, zdev.getPid(), reqCount);
					// 设置过期时间为一天
					Date date = Date
							.from(LocalDateTime.now().with(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant());
					redis15.expireAt(USER_REQUEST_INFO_RECORD_KEY, date);
				} else {
					redis15.opsForHash().put(USER_REQUEST_INFO_RECORD_KEY, zdev.getPid(), reqCount);
				}
				String utoken = AesEncryptUtils.encryptBySalt(result.getPid());
				redis0.opsForHash().put("CAT_DEV_LOGIN_TOKEN", result.getPid(), utoken);
				result.setUtoken(utoken);
			} else {
				result.setUtoken((String) redis0.opsForHash().get("CAT_DEV_LOGIN_TOKEN", result.getPid()));
			}
			// 检查更新邀请信息
			updateInviteInfo(rtype, zdev.getUnionid(), result);
		}

		// 查询连续签到天数
		CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(zdev.getPid());
		result.setSigns(historyResp.getSigns());
		String endDate = historyResp.getEndDate();
		// 如果最后签到的日期不是为今日,则记为今日未签到
		if (endDate == null || !endDate.equals(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD))) {
			// 今天未签到
			result.setSigned(0);
		} else {
			// 如果连续签到天数为0,则说明今日已拒签
			if (historyResp.getSigns() == 0) {
				result.setSigned(-1);
			} else {
				result.setSigned(1);
			}
		}

		// 获取当前签到红包是否领取
		result.setSignedpcks(getSignedReceiveStatus(zdev.getPid()) == true ? 1 : 0);

		// 查询现金豆数量与现金红包
		CatDevUserInfoResp beansData = cacheService.getCatDevBeansData(zdev.getPid());
		result.setBeans(beansData.getBeans());
		result.setAbeans(beansData.getAbeans());
		result.setJbeans(beansData.getJbeans());
		result.setBeans(cacheService.getCatDevLastBeans(zdev.getPid()));
		result.setRpt(cacheService.getCatDevLastRMB(zdev.getPid()));

		// 查询正在入账金额
		Long amount = longDao.selectOne(new CatDevOrderResp(zdev.getPid(), 0, 10), "getOrderAmountByStatus");
		result.setRcode(amount);

		// 1.1.6版本查询淘礼金信息
		TLJInfo tljInfo = tljDao.selectOne(new CatDevUserInfo(result.getPid()), "getTljInfo");
		if (tljInfo != null) {
			result.setTljInfo(tljInfo);
		}

		CatDevUserInfoResp.CashBalanceInfo balanceInfo = cacheService.getUserBalance(zdev.getPid());
		balanceInfo.setReadyRebate(amount);
		result.setBalanceInfo(balanceInfo);

		// 设置用户昵称
		result.setNikename(AesEncryptUtils.decrypt(zdev.getNikename()));

		// 判断是否已填写身份证号
		if (result.getIdcard().length() == 18) {
			// 对身份证号进行处理
			result.setIdcard(result.getIdcard().replaceAll("(?<=[\\d]{4})\\d(?=[\\d]{4})", "*"));
		}

		// 设置奖品碎片信息
		result.setPrizeInfoResp(catGameService.getCVSPrizeInfoResp(zdev.getPid()));

		// 设置订单状态
		Integer orderNumber = cacheService.getUserOrderNumber(zdev.getPid());
		CatDevCountResp countResp = new CatDevCountResp();
		// 设置订单数量
		countResp.setOrderRebateCount(orderNumber == null ? 0 : orderNumber);
		result.setOrderStatus(orderNumber == null ? 0 : 1);
		// 获取是否下单过大额券
		Integer number = cacheService.getUserDaEOrderNumber(result.getPid());
		result.setSupercoupon(number == null || number == 0 ? 0 : 1);
		int addOrderNum = newAddOrderHistoryRepository.countByPid(result.getPid());
		// 获取用户新增订单数量
		countResp.setAddOrderCount(addOrderNum);
		// 获取用户待提升返利概率订单数量
		int promotedOrderCount = cacheService.getNotPromotedOrderCount(result.getPid());
		countResp.setNotPromotedCount(promotedOrderCount);
		result.setCountResp(countResp);

		if (addOrderNum > 0) {
			// 设置响应数据成功,清除通知新增订单数据
			asyncService.deleteNewAddOrderHistory(result.getPid());
			// 更新任务状态
			userTaskRecordDao.update(new CatDevUserTaskRecord(result.getPid(), 2), "updateTaskStatus");
		}

		// 设置广告开关状态
		result.setAdStatus(cacheService.getCatAppAdStatus(rtype, cid, vscode));

		// 获取用户打开应用次数
		Integer openNum = (Integer) redis15.opsForHash().get(USER_OPEN_NUM, zdev.getPid());
		if (openNum == null) {
			// 判断签到次数，一天为一次
			Integer count = signedHistoryRepository.countByUnionid(zdev.getUnionid());
			openNum = count;
		}
		// 如果为首页位置请求则，打开次数增加
		if (pindex == 0) {
			openNum++;
			saveUserOpenNum(zdev.getPid(), openNum);
		}
		// 判断是否为新用户
		if (openNum > 4) {
			result.setUtype(1);
		}
		// 设置弹窗
		result.setPopupId(getPopupId(pindex, openNum, zdev.getPid()));
		// 弹窗逻辑去除，新老用户均不弹窗
		result.setPopupId(0);
		if (!TJKUtils.parse2LocalDateTime(zdev.getCtime()).plusDays(1).isBefore(LocalDateTime.now())) {
			/* 判断是否已注册1天,如果未超过1天(24小时)判断新用户提现 */
			// 判断用户是否满足新人提现条件
			result.setNewUserRemit(isAbleNewUserRemit(result.getPid()) ? 1 : 0);
		}

		// 查询是否有反馈回复信息
		if (userFeedbackHistoryRepository.countByUserIdAndStatus(result.getPid(), 2) > 0) {
			result.setIsFeedbackMsg(1);
		}
		return result;
	}

	@Override
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	public String getTbOAuth2Url(Integer ctype, int rtype, CatDevUserInfo zdev, String pid) {
		String client_id = "28121056";
		String info = "关系授权";

//		if(ctype==null||ctype==0) {
//			client_id = "28121056";
//		}else if(ctype==1) {
//			client_id = "29302482";
//			rtype+=10;
//		}else if(ctype==2){
//			client_id = "29515689";
//			rtype+=20;
//		}

//			if (rtype == 0) {
//				client_id = "25650123";
//				client_secret = "1916f2cbd3354d56be0f822f349692c6";
//			} else if (rtype == 1) {
//				client_id = "26032814";
//				client_secret = "30ea879a0be62f192d07ad218d9ea2bb";
//			}
//			String basePath = "https://dev.adsteam.cn";
//			
//			if(SpringContextUtil.isDev()) {
//				basePath="http://ywtrps.natappfree.cc";
//			}

		String basePath = configs.getTboauth();
		log.info("-TBOAuthUrl-->" + basePath);
		if (StringUtils.isBlank(basePath)) {
			basePath = "https://oauth.jiuqumao.cn";
		}

		String redirect_uri = basePath + "/cms/api/v1/code/public/getcode?param701="
				+ AesEncryptUtils.encrypt(pid + "_tbk_" + info + "_tbk_" + info + "_tbk_" + (rtype + 10));
		String location = "https://oauth.m.taobao.com/authorize?response_type=code&client_id=" + client_id + "&stat=1"
				+ "&redirect_uri=" + redirect_uri;
		return location;
	}

	@Override
	@RedisEvicts(before = false, evict = { @RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = {
			"+#zdev.pid", "+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	public Boolean updSex(CatDevUserInfo zdev, Integer rtype, String pid, Integer sex) {
		zdev.setSex(sex);
		/* 用户信息加上缓存之后需清除缓存中的用户信息 */
		return catDao.update(zdev);
	}

	@Override
	public ResultPage<CatDevRemitRecordResp> remitList(String pid, Pages pages, Integer mode) {
		CatDevRemitRecordResp infoResp = new CatDevRemitRecordResp(pid);
		infoResp.setRtype(mode);
		return remitDao.listAndPages(infoResp, "getRemitListPlus", pages);
	}

	@Override
	public CatDevRemitRecordResp remit(int rtype, Integer appId, String pid, int qtype, int mode, String zaccount,
			String zrealname, long tmoney) {
		String nowTimeString = TJKUtils.DateTime();
		// 新用户首次一元体验提现
		if (mode == 3 && tmoney == 0) {
			tmoney = 100;
		}
		CatDevRemitInfo entity = new CatDevRemitInfo(pid, TJKUtils.DateTime(TJKUtils.YYYY_MM_DD), qtype, zaccount,
				zrealname, tmoney, nowTimeString, "");
		entity.setLtime(nowTimeString);
		entity.setRtype(mode);
		// 获取用户微信信息
		CatDevUserInfo catDevUserInfo = getCatDevUserInfoByPid(pid);
		entity.setUnionid(catDevUserInfo.getUnionid());
		entity.setOpenid(catDevUserInfo.getOpenid());
		/* 大于5元审核提现 */
//		if(mode==0 && tmoney>500) {
//			entity.setDtype(1);
//		}
		if (mode == 1 || mode == 2) {
			// 清除Redis中的记录
			asyncService.updateCatDevInviteAwardRecord(pid, 0, 0, "", 0);
		}
		/* 如果为直接邀请提现,大于10元审核提现 */
		if (mode == 1 && tmoney >= 10 * 100) {
			entity.setDtype(1);
		} else if (mode == 0 && tmoney > 10 * 100) {
			entity.setDtype(1);
		}
		/* 5088邀请提现，审核后提现 */
		if (mode == 5) {
			entity.setDtype(1);
		}

		CatDevRemitInfo remit = catDevRemitInfoRepository.saveAndFlush(entity);
		if (remit != null) {
			// 如果为新用户首次提现，即完成新人任务
			if (mode == 3) {
				// 更新任务状态
				userTaskRecordDao.update(new CatDevUserTaskRecord(pid, 3), "updateTaskStatus");
			}
			/* 立即到账，直接打款 */
			if (remit.getDtype() == 0) {
				Map<String, String> payMap = new HashMap<String, String>();
				payMap.put("unionid", remit.getUnionid());
				payMap.put("amount", "" + tmoney);
				payMap.put("partner_trade_no", remit.getOid());
				payMap.put("dtype", appId + "");

				/* 被邀请好友状态，包含（1，xxx注册成功。2，xxx第二天打开APP。3xxx第三天打开APP。4，xxx购物奖励金）xxx为被邀请人微信名称 */
				// payMap.put("info", "");

				/* 微信打款 */
				if (qtype == 0) {
					redis17.opsForList().leftPush(REMIT_WX_KEY, payMap);
				}
//				else if(mode==1) {
//					/* 支付宝打款 */
//					payMap.put("zaccount", remit.getZaccount());
//					payMap.put("zrealname", remit.getZrealname());
//					redis17.opsForList().leftPush(REMIT_ZFB_KEY, payMap);
//				}
			} else {
				// 审核到账，发送审核中通知提醒,获取accessToken
				String accessToken = cacheService.getWechatAccessToken(configs.getWxAppid(), configs.getWxSecret());
				CatDevUserInfo devUserInfo = getCatDevUserInfoByPid(pid);
				WxUserInfo userInfo = wxUserInfoRepository.findByUnionid(devUserInfo.getUnionid());
				String tid = "u8Gz6Qn-uwW4NGzojK0ijIP3kiFwIMzmAmc5q7arAEE";
				String url = "https://engine.seefarger.com/index/activity?appKey=4TFNJ2PU614pNANuW3wWuZjhgarN&adslotId=324201";
				/*
				 * 您的提现金额已开始审核，预计1-3个工作日即可到账，请耐心等待 提现申请时间：提现申请的当前时间 提现申请金额：提现申请金额，xxx元
				 * 提现手续费：0.00不需要手续费0.00元 温馨提示：节假日操作顺延至下一个工作日开始审核
				 */
				List<String> datas = new ArrayList<String>();
				datas.add("您的提现金额已开始审核，预计1-3个工作日即可到账，请耐心等待");// 例子中第一条
				datas.add(TJKUtils.DateTime());
				datas.add((tmoney / 100.0) + "元");
				datas.add("0.0元");
				datas.add("节假日操作顺延至下一个工作日开始审核");
				asyncService.templateMSG(accessToken, userInfo.getOpenid(), url, datas, tid);
			}
			CatDevRemitRecordResp recordResp = new CatDevRemitRecordResp();
			BeanUtils.copyProperties(remit, recordResp);
			return recordResp;
		}
		return null;
	}

	@Override
	public boolean beansConvert(int rtype, String pid, long beans) {
		// 计算所得现金豆数
		long rmb = beans / 100;
		CatDevBeansConvertInfo convertInfo = new CatDevBeansConvertInfo(TJKUtils.DateTime(), pid, beans, rmb, 1,
				TJKUtils.DateTime());
		return beansConvertInfoRepository.saveAndFlush(convertInfo) == null ? false : true;
	}

	@Override
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	@Transactional
	public UserTaskData updPhone(int rtype, CatDevUserInfo zdev, String pid, String phone) {
		CatDevUserInfo userInfo = new CatDevUserInfo();
		userInfo.setPid(pid);
		userInfo.setPhone(phone);
		if (catDao.update(userInfo, "updatePhone")) {
			String taskName = "完善手机号信息";
			// 更新任务状态
			CatDevUserTaskRecord taskRecord = newUserTaskRecordRepository.findByPidAndTaskType(pid, 1);
			if (taskRecord == null) {
				return new UserTaskData(taskName, 1, 0, 0, 1, 1, 1);
			}
			int taskStatus = taskRecord.getTaskStatus();
			if (taskStatus == 0) {
				taskRecord.setTaskStatus(1);
				taskRecord.setLtime(TJKUtils.DateTime());
				taskRecord.setReceiveStatus(1);
				taskRecord.setTaskNum(1);
				newUserTaskRecordRepository.saveAndFlush(taskRecord);
			}
			UserTaskData data = new UserTaskData();
			BeanUtils.copyProperties(taskRecord, data);
			if (taskStatus == 0) {
				data.setReceiveStatus(2);
			}
			data.setTaskContent(taskName);
			return data;
		}
		return null;
	}

	@Override
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	public Boolean updInfo(int rtype, CatDevUserInfo zdev, String pid, String icon, String nikename) {
		CatDevUserInfo userInfo = new CatDevUserInfo();
		userInfo.setPid(pid);
		userInfo.setNikename(AesEncryptUtils.encrypt(nikename));
		userInfo.setIcon(icon);
		return catDao.update(userInfo, "updateNikenameAndIcon");
	}

	@Override
	public CatDevSignedHistoryResp getSignedInfo(Integer rtype, String pid, String version) {
		/* 1.七日签到信息初始化（未签到，自动签到，返回连续签到的天数） */
		// 查询连续签到天数
		CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(pid);
		int days = historyResp.getSigns();
		String endDate = historyResp.getEndDate();
		boolean isOldVersion = Integer.parseInt(version) < 103;
		// 如果最后签到的日期不是为今日,则新建今天的签到记录
		if (endDate == null || !endDate.equals(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD))) {
			// 设置为今日首次签到
//			historyResp.setIsFirst(1);
			// 判断是否为七天中的第一天(起点) 0.非起点 1.第一天
			int isStart = 0;
			/*
			 * 1. days==0 无连续签到记录,从当前天开始为第一天 2. days==7 若已连续签到七天,则今天为下一个周期的起点第一天
			 */
			if (days == 0 || days == 7) {
				isStart = 1;
				// 将连续签到天数设为一天
				days = 1;
			} else {
				isStart = 0;
				// 增加连续签到天数
				days++;
			}
			CatDevSignedHistory catDevSignedHistory = new CatDevSignedHistory(pid,
					TJKUtils.DateTime(TJKUtils.YYYY_MM_DD), isStart, 1, TJKUtils.DateTime());
			// 保存记录
			if (signedHistoryRepository.saveAndFlush(catDevSignedHistory) == null) {
				log.error("getSignedInfo:签到历史记录保存失败pid=" + pid);
				return null;
			}

			// 设置连续签到天数
			historyResp.setSigns(days);
		}

		/* 2.60分钟一次签到金币（从凌晨计时开始），本时间段未领取，自动领取，返回本阶段领取状态以及现金豆数，已领取，返回领取状态 */
		// 获取当前时间
		Calendar calendar = Calendar.getInstance();
		int minute = calendar.get(Calendar.MINUTE);
		String nowTime;
		CatDevSignedBeansHistory signedBeansHistory;
//		boolean receiveStatus = getSignedReceiveStatus(pid);
		boolean receiveStatus = true;
		// 如果此时正处于整小时节点上则直接领取
		if (minute >= 60) {
			// 当前时间大于60分， 判断60分的红包是否领取
			calendar.set(Calendar.MINUTE, 60);
			calendar.set(Calendar.SECOND, 0);
			nowTime = DateAPIUtils.dateToString(calendar.getTime(), DateAPIUtils.YYYYMMDDHHMMSS);
			signedBeansHistory = signedBeansHistoryRepository.findByPidAndStime(pid, nowTime);
			receiveStatus = signedBeansHistory == null ? false : true;
		} else {
			// 小于60且大于0，判断0分的红包是否领取
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			nowTime = DateAPIUtils.dateToString(calendar.getTime(), DateAPIUtils.YYYYMMDDHHMMSS);
			signedBeansHistory = signedBeansHistoryRepository.findByPidAndStime(pid, nowTime);
			receiveStatus = signedBeansHistory == null ? false : true;
		}

		if (receiveStatus == true) {
			// 如果为已领取，则直接返回
			historyResp.setSignedpcks(1);
			return historyResp;
		} else {
			historyResp.setSignedpcks(0);
		}

		// 3. 判断是否为第七天签到如果为第七天签到的第一次签到则奖励888个现金豆
		// 奖励现金豆数
		int beanNum = 0;
		int isSeventh = 0;
		int fstatus = 0;
		List<CatDevSignedBeansHistory> list = signedBeansHistoryDao.list(new CatDevSignedBeansHistory(pid),
				"getTodaySignInList");
		if (historyResp.getSigns() == 7 && (list == null || list.size() < 1)) {
			beanNum = 688;
			isSeventh = 1;
			// 不支持翻倍
			fstatus = -1;
		} else {
			beanNum = RandomUtils.nextInt(200, 300);
		}

		// 保存此次签到领取记录,如果为当天首次签到，则领取状态为待领取
		CatDevSignedBeansHistory beansHistory = new CatDevSignedBeansHistory(pid, nowTime, beanNum, isSeventh, 1,
				TJKUtils.DateTime());
		beansHistory.setFstatus(fstatus);
		signedBeansHistoryRepository.saveAndFlush(beansHistory);
		historyResp.setFid(beansHistory.getFid());
		historyResp.setFstatus(fstatus);
		historyResp.setBeans(beanNum);
		historyResp.setSignedpcks(2);
		return historyResp;
	}

	/**
	 * 判断是否已领取签到现金豆
	 * 
	 * @param pid
	 * @return
	 */
	public boolean getSignedReceiveStatus(String pid) {
		// 获取当前时间
		Calendar calendar = Calendar.getInstance();
		int minute = calendar.get(Calendar.MINUTE);
		String nowTime;
		CatDevSignedBeansHistory signedBeansHistory;
		// 如果此时正处于半小时节点上则直接领取
		if (minute >= 30) {
			// 当前时间大于30分， 判断30分的红包是否领取
			calendar.set(Calendar.MINUTE, 30);
			calendar.set(Calendar.SECOND, 0);
			nowTime = DateAPIUtils.dateToString(calendar.getTime(), DateAPIUtils.YYYYMMDDHHMMSS);
			signedBeansHistory = signedBeansHistoryRepository.findByPidAndStime(pid, nowTime);
			return signedBeansHistory == null ? false : true;
		} else {
			// 小于30且大于0，判断0分的红包是否领取
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			nowTime = DateAPIUtils.dateToString(calendar.getTime(), DateAPIUtils.YYYYMMDDHHMMSS);
			signedBeansHistory = signedBeansHistoryRepository.findByPidAndStime(pid, nowTime);
			return signedBeansHistory == null ? false : true;
		}
	}

	@Override
	public CatCashBonusHistoryResp getCashBonusInfo(int rtype, String pid, Pages pages) {
		CatCashBonusHistoryResp resp = new CatCashBonusHistoryResp();
		// 查询可提现金额
		resp.setKcode(cacheService.getCatDevLastRMB(pid));
		// 累计到账金额
		CatDevUserInfoResp devUserInfo = catDevUserInfoRespDao.selectOne(new CatDevUserInfo(pid),
				"getCatDevCumulativeRMB");
		resp.setLcode(devUserInfo == null ? 0 : devUserInfo.getRpt());
		// 入账中金额
		Long amount = longDao.selectOne(new CatDevOrderResp(pid, 0, 10), "getOrderAmountByStatus");
		resp.setRcode(amount);

		// 收入记录
		resp.setInList(cashBonusDao.list(new CatDevUserInfo(pid), "getIncomeList"));
		// 支出记录
		List<CatDevRemitRecordResp> list = remitDao.list(new CatDevRemitRecordResp(pid, new int[] { 0, 3 }),
				"getRemitList");
		List<CashBonus> outList = resp.getOutList() == null ? new ArrayList<CashBonus>() : resp.getOutList();
		StringBuffer stringBuffer = new StringBuffer("提现");
		for (CatDevRemitRecordResp catDevRemitInfoResp : list) {
			stringBuffer.append(catDevRemitInfoResp.getQtype() == 0 ? "微信" : "支付宝");
			outList.add(new CashBonus(stringBuffer.toString(), catDevRemitInfoResp.getDmoney(),
					catDevRemitInfoResp.getCtime()));
			stringBuffer.delete(2, stringBuffer.length());
		}
		resp.setOutList(outList);
		return resp;
	}

	@Override
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	public Boolean updAlipay(Integer rtype, CatDevUserInfo zdev, String pid, String account, String realname) {
		zdev.setPid(pid);
		zdev.setZaccount(account);
		zdev.setZrealname(realname);
		return catDao.update(zdev, "updateAlipayInfo");
	}

	@Override
	public boolean getRegisterIncome(int rtype, String pid, CatDevRegisterIncomeHistory zdev) {
		zdev.setLstatus(1);
		zdev.setLtime(TJKUtils.DateTime());
		return catDevRegisterIncomeHistoryRepository.saveAndFlush(zdev) != null;
	}

	@Override
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	public boolean authentication(Integer rtype, CatDevUserInfo zdev, String realname, String idcard, String purl,
			String burl) {
		zdev.setFidcard1(purl);
		zdev.setFidcard2(burl);
		zdev.setIdcard(idcard);
		zdev.setRealname(realname);
		zdev.setFstatus(1);
		return catDao.update(zdev, "updateIdCard");
	}

	@Override
	public CatDevBeanVideoHistoryResp getBeansByVideo(Integer rtype, String pid, int ltype) {
		CatDevBeanVideoHistory videoHistory = new CatDevBeanVideoHistory(pid);
		// 福利中心看视频奖励50个现金豆(在任务记录表加，此表纪录),弹窗奖励200现金豆
		videoHistory.setBeans(ltype == 0 ? 0 : 200);
		videoHistory.setLtype(ltype);
		videoHistory.setCtime(TJKUtils.DateTime());
		videoHistory.setLtime(TJKUtils.DateTime());
		if (beanVideoHistoryRepository.saveAndFlush(videoHistory) == null) {
			// 保存失败
			return null;
		}
		// 查询看视频领金豆信息
		CatDevBeanVideoHistoryResp videoHistoryResp = cacheService.getBeanVideoHistory(pid, ltype);
		videoHistoryResp.setBeans((int) videoHistory.getBeans());
		return videoHistoryResp;
	}

	@Override
	public CatDevWelfareInfoResp getWelfareInfo(Integer rtype, String pid) {
		// 查询连续签到天数
		CatDevWelfareInfoResp result = new CatDevWelfareInfoResp(pid);
		CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(pid);
		result.setSigns(historyResp.getSigns());
		String endDate = historyResp.getEndDate();
		// 如果最后签到的日期不是为今日,则新建今天的签到记录
		if (endDate == null || !endDate.equals(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD))) {
			// 今天未签到
			result.setSigned(0);
			result.setSignInStatus(0);
		} else {
			result.setSigned(1);
			// 今日已签到查询是否翻倍
			CatDevSignedBeansHistory signInStatus = cacheService.getTodaySignInStatus(pid, LocalDate.now().toString());
			if (signInStatus.getFstatus() == 0) {
				// 未翻倍
				result.setSignInStatus(1);
				// 翻倍ID
				result.setFid(signInStatus.getFid());
			} else {
				// 已翻倍
				result.setSignInStatus(2);
			}
		}

		// 获取当前签到红包是否领取
		result.setSignedpcks(getSignedReceiveStatus(pid) == true ? 1 : 0);

		// 查询现金豆数量与现金红包
		CatDevUserInfoResp beansData = cacheService.getCatDevBeansData(pid);
		result.setBeans(beansData.getBeans());
		result.setAbeans(beansData.getAbeans());
		result.setJbeans(beansData.getJbeans());
		result.setBeans(cacheService.getCatDevLastBeans(pid));
		result.setRpt(cacheService.getCatDevLastRMB(pid));
		// 查询今日福利中心看视频领金豆数据
		result.setBeanVideoHistoryResp(cacheService.getBeanVideoHistory(pid, 0));

		// 设置游戏获取的金豆数与新用户任务
		long beansByGame = cacheService.getCatDevBeansByGame(pid);
		result.setGameBeans(beansByGame);

		CatDevUserInfo userInfo = getCatDevUserInfoByPid(pid);
		// 查询新人任务完成情况
		List<CatDevUserTaskRecord> list = newUserTaskRecordRepository.findByPidAndTaskAttributeOrderByTaskType(pid, 0);

		List<UserTaskData> collect = createUserTaskData(list, userInfo, beansByGame);
		result.setNewUserTaskData(collect);
		// 获取每日任务列表
		List<CatDevUserTaskRecord> everydayList = newUserTaskRecordRepository
				.queryByPidAndTaskAttributeOrderByTaskType(pid, 1);
		if (everydayList == null || everydayList.size() == 0) {
			// 新建每日任务
			List<CatDevUserTaskConfig> taskConfigList = catDevUserTaskConfigRepository
					.findByTaskAttributeOrderByTypeId(1);
			everydayList = taskConfigList.stream().map(config -> {
				return new CatDevUserTaskRecord(config.getTypeId(), pid, config.getBeanNum(), TJKUtils.DateTime(), 1);
			}).collect(Collectors.toList());
			newUserTaskRecordRepository.saveAll(everydayList);
			newUserTaskRecordRepository.flush();
		}
		// 校验任务是否已完成
		List<UserTaskData> everydayTaskData = createUserTaskData(everydayList, userInfo, beansByGame);
		result.setEverydayTaskData(everydayTaskData);

		// 设置为不显示新人任务
		// 新用户可享1元极速提现，判断是否为新用户
		int count = catDevRemitInfoRepository.countByPidAndRtypeInAndTstatusNot(pid, Arrays.asList(3), -1);
		// 判断是否有一元提现提现记录，如果有则判断是否已过期新手任务
		result.setIsFirst(count > 0 ? 1 : 0);
		return result;
	}

	/**
	 * 将CatDevUserTaskRecord类型转换为响应类型, 校验任务完成情况
	 * 
	 * @date 2020-06-01 10:58:37
	 * @param list
	 * @param userInfo
	 * @param beansByGame
	 * @return
	 */
	private List<UserTaskData> createUserTaskData(List<CatDevUserTaskRecord> list, CatDevUserInfo userInfo,
			long beansByGame) {
		if (list == null) {
			return null;
		}
		List<UserTaskData> collect = list.stream().map(obj -> {
			UserTaskData taskData = new UserTaskData();
			BeanUtils.copyProperties(obj, taskData);
			taskData.setTaskType(obj.getTaskType());
			taskData.setTaskNum(obj.getTaskNum());
			// 判断任务为已领取或者已取消，则设置响应参数为不显示
			if (obj.getReceiveStatus() == 1 || obj.getTaskStatus() == -1) {
				taskData.setIsShow(0);
			} else if (obj.getTaskStatus() == 0) {
				// 如果任务状态为未完成,则判断是否为快速提现任务(快速提现任务有时间与邀请关系限制)
				if (obj.getTaskType() == 3) {
					// 保存任务为失效状态
					ExtendMethod<CatDevUserTaskRecord, CatDevUserTaskRecord> m = (param) -> {
						param.setLtime(TJKUtils.DateTime());
						param.setReceiveStatus(-1);
						param.setTaskStatus(-1);
						return newUserTaskRecordRepository.saveAndFlush(param);
					};
					if (TJKUtils.parse2LocalDateTime(userInfo.getCtime()).plusDays(7).isBefore(LocalDateTime.now())) {
						// 判断是否已注册七天
						// 设置为不显示新人任务
						taskData.setIsShow(0);
						taskData.setReceiveStatus(-1);
						taskData.setTaskStatus(-1);
						m.executeMethod(obj);
					} else {
						// 注册时间未超过七天
						taskData.setIsShow(1);
						// 判断任务是否完成
						taskData.setTaskStatus(beansByGame >= DrawProportionUtil.NEW_USER_TASK_BAENS_NUM ? 1 : 0);
						if (beansByGame >= DrawProportionUtil.NEW_USER_TASK_BAENS_NUM) {
							obj.setLtime(TJKUtils.DateTime());
							obj.setTaskStatus(1);
							newUserTaskRecordRepository.saveAndFlush(obj);
						}
					}
				} else if (obj.getTaskType() == 2) {
					// 判断用户是否已经有订单记录
					Integer number = cacheService.getOrderNumber(userInfo.getPid(), userInfo.getPid(), null);
					if (number != null && number > 0) {
						// 设置为待领取状态
						obj.setLtime(TJKUtils.DateTime());
						obj.setTaskStatus(1);
						newUserTaskRecordRepository.saveAndFlush(obj);
						taskData.setTaskStatus(1);
					}
					taskData.setIsShow(1);
				} else if (obj.getTaskType() == 8) {
					// 每日首单奖励
					// 判断用户是否已经有订单记录
					Integer number = cacheService.getOrderNumber(userInfo.getPid() + LocalDate.now().toString(),
							userInfo.getPid(), LocalDate.now().toString());
					if (number != null && number > 0) {
						// 设置为待领取状态
						obj.setLtime(TJKUtils.DateTime());
						obj.setTaskStatus(1);
						newUserTaskRecordRepository.saveAndFlush(obj);
						taskData.setTaskStatus(1);
					}
					taskData.setIsShow(1);
				} else {
					taskData.setIsShow(1);
				}
			} else if (obj.getTaskStatus() == 1 && obj.getReceiveStatus() == 0) {
				// 如果为已完成任务，但未领取的状态
				taskData.setIsShow(1);
			}
			return taskData;
		}).collect(Collectors.toList());
		return collect;
	}

	@Override
	public CatDevRemitInfoResp getRemitInfo(Integer rtype, String pid) {
		CatDevRemitInfoResp result = new CatDevRemitInfoResp(pid);
		// 获取用户信息
		CatDevUserInfoResp userInfoResp = cacheService.getCatDevUserLoginInfo(pid);
		BeanUtils.copyProperties(userInfoResp, result);
		// 解密昵称
		result.setNikename(AesEncryptUtils.decrypt(result.getNikename()));

		// 查询连续签到天数
		CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(pid);
		String endDate = historyResp.getEndDate();
		// 如果最后签到的日期不是为今日,则记为今日未签到
		if (endDate == null || !endDate.equals(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD))) {
			// 今天未签到
			result.setSigned(0);
		} else {
			// 判断今天的签到状态,签到天数为0是代表今日已拒绝签到
			result.setSigned(historyResp.getSigns() == 0 ? -1 : 1);
		}

		// 获取提现连续签到天数
		CatDevSignedHistoryResp whistoryResp = signedHistoryRespDao.selectOne(new CatDevSignedHistory(pid),
				"getSignInNumberDays");
		result.setWsigns(whistoryResp.getSigns());

		int signDays = 2;
		// 新用户提现,
		if (isAbleNewUserRemit(pid)) {
			signDays = 0;
		}

		// 设置可快速提现的连续签到天数条件
		result.setNeedwsigns(new int[] { signDays, 3, 8 });

		// 设置剩余现金豆数与现金红包数量
		result.setBeans(cacheService.getCatDevLastBeans(pid));
		result.setRpt(cacheService.getCatDevLastRMB(pid));

		// 查询正在入账金额
		Long amount = longDao.selectOne(new CatDevOrderResp(pid, 0, 10), "getOrderAmountByStatus");

		CatDevUserInfoResp.CashBalanceInfo balanceInfo = cacheService.getUserBalance(pid);
		balanceInfo.setReadyRebate(amount);
		result.setBalanceInfo(balanceInfo);

		// 设置关注微信公众号状态
		Integer isFocusWeChat = getIsFocusWeChat(rtype, pid, getCatDevUserInfoByPid(pid).getUnionid());
		result.setIsFocusWx(isFocusWeChat);

		CatDevUserInfo userInfo = getCatDevUserInfoByPid(pid);
		// 判断设不设置新用户提现按钮
		boolean isShow = false;
		if (!TJKUtils.parse2LocalDateTime(userInfo.getCtime()).plusDays(7).isBefore(LocalDateTime.now())) {
			/* 判断是否已注册七天,如果未超过七天判断新用户提现 */
			// 如果不存在邀请关系,则显示
			CatDevRelation inviteInfo = cacheService.getInviteRelationByPid(pid);
			if (inviteInfo == null) {
				isShow = true;
			}
		}
		// 设置为不显示新人任务
		// 新用户可享1元极速提现，判断是否为新用户
		int count = catDevRemitInfoRepository.countByPidAndRtypeInAndTstatusNot(pid, Arrays.asList(3), -1);
		// 判断是否有一元提现提现记录，如果有则判断是否已过期新手任务
		result.setIsFirst(count > 0 ? 0 : isShow ? 1 : 0);
		if (count > 0) {
			// 已有1元提现记录，则不显示
			isShow = false;
		}
		if (isShow) {
			// 判断是否完成新人任务
			long beansByGame = cacheService.getCatDevBeansByGame(pid);
			if (beansByGame >= DrawProportionUtil.NEW_USER_TASK_BAENS_NUM) {
				result.setIsFinishTaskNew(1);
			} else {
				// 未完成新人任务，判断是否有提现失败记录(针对2.3-2.5这批用户)
				Integer selectOne = intDao.selectOne(new CatDevRemitRecordResp(pid), "selectFailCountByNewUser");
				if (selectOne != null && selectOne > 0) {
					result.setIsError(1);
				}
			}
		}

		// 获取是否下单过大额券
		Integer number = cacheService.getUserDaEOrderNumber(pid);
		result.setSupercoupon(number == null || number == 0 ? 0 : 1);
		return result;
	}

	@Override
	public boolean isAbleNewUserRemit(String pid) {
		CatDevUserInfo userInfo = getCatDevUserInfoByPid(pid);
		// 判断设不设置新用户提现按钮
		boolean isShow = false;
		if (!TJKUtils.parse2LocalDateTime(userInfo.getCtime()).plusDays(7).isBefore(LocalDateTime.now())) {
			/* 判断是否已注册七天,如果未超过七天判断新用户提现 */
			isShow = true;
		}
		// 设置为不显示新人任务
		// 新用户可享1元极速提现，判断是否为新用户
		int count = catDevRemitInfoRepository.countByPidAndRtypeInAndTstatusNot(pid, Arrays.asList(0, 3), -1);
		return isShow && count == 0;
	}

	@Override
	public Integer getIsFocusWeChat(Integer rtype, String pid, String unionid) {
		WxUserInfo userInfo = wxUserInfoRepository.findByUnionid(unionid);
		return userInfo == null ? 0 : 1;
	}

	@Override
	public ResultPage<CatDevRemitRecordResp> remitWeChatList(String code, Pages pages, Integer mode) {
		// 获取微信的信息
		String openid = cacheService.getWeChatOpenIdByCode(code);
		if (StringUtils.isEmpty(openid)) {
			return null;
		}
		WxUserInfo wxUserInfo = wxUserInfoRepository.findByOpenid(openid);
		if (wxUserInfo == null) {
			return null;
		}
		// 查询用户PID
		CatDevUserInfo userInfo = getCatDevUserInfoByUnionid(wxUserInfo.getUnionid());
		if (userInfo == null) {
			return null;
		}
		return remitList(userInfo.getPid(), pages, mode);
	}

	@Override
	public Map<String, Object> getSignedInfoDouble(CatDevSignedBeansHistory beansHistory) {
		beansHistory.setFstatus(1);
		beansHistory.setDcount(beansHistory.getDcount() * 2);
		CatDevSignedBeansHistory history = signedBeansHistoryRepository.saveAndFlush(beansHistory);
		if (history == null) {
			return null;
		}
		Map<String, Object> map = new HashMap<>();
		map.put("dcount", history.getDcount());
		map.put("fstatus", 1);
		return map;
	}

	@Override
	@Transactional
	@RedisEvicts(before = false, evict = {
			@RedisEvict(rtype = 2, db = 13, key = "CAT_DEV_INFO", hashKeys = { "+#zdev.pid",
					"+#zdev.unionid", "+#zdev.phone", "+#zdev.userid" }) })
	public boolean accountLogout(String pid, CatDevUserInfo zdev) {
		// 清除缓存中的用户数据CAT_DEV_LOGIN_TOKEN
		redis0.opsForHash().delete("CAT_DEV_LOGIN_TOKEN", pid);
		redis0.opsForHash().delete("CAT_DEV_PUSH_RED_PACKET_DATA", pid);

		// 将账号状态设置为已注销
		CatDevUserInfo devUserInfo = getCatDevUserInfoByPid(pid);
		devUserInfo.setIstatus(2);
		devUserInfo.setNikename(AesEncryptUtils.encrypt("已注销用户"));
		devUserInfo.setUtype(1);
		return catDevUserInfoRepository.saveAndFlush(devUserInfo) == null ? false : true;
	}

	@Override
	public CatDevUserInfoResp accountLogin(Integer rtype, String account, HttpServletRequest request) {
		CatDevUserInfoResp result = cacheService.getCatDevUserLoginInfo(account);
		if (result != null) {
			String utoken = AesEncryptUtils.encryptBySalt(result.getPid());
			redis0.opsForHash().put("CAT_DEV_LOGIN_TOKEN", result.getPid(), utoken);
			result.setUtoken(utoken);

			/* 记录直接邀请用户第几次登录 */
			// 判断今天是否已领取
			CatDevZJInviteIncomeHistory zjInvite = catDevZJInviteIncomeHistoryRepository
					.findZJInviteLast(result.getPid());
			// 今天未领取
			if (zjInvite == null) {
				CatDevZJInviteIncomeHistory taskHistory = catDevZJInviteIncomeHistoryRepository
						.findZJInviteOpenTaskHistory(result.getPid());
				if (taskHistory != null) {
					taskHistory.setLtime(TJKUtils.DateTime());
					taskHistory.setIstatus(1);
					catDevZJInviteIncomeHistoryRepository.saveAndFlush(taskHistory);
					/* 邀请好友任务完成,记录邀请人的通知缓存中 */
					asyncService.updateCatDevInviteAwardRecord(taskHistory.getYid(), 1, taskHistory.getIncome(),
							result.getNikename(), taskHistory.getItype());
				}
			}
			// 查询未完成的订单任务
			CatDevZJInviteIncomeHistory history = catDevZJInviteIncomeHistoryRepository
					.findByPidAndItypeAndIstatus(result.getPid(), 4, 0);
			if (history != null) {
				// 查询用户已完成订单数量
				Integer count = intDao.selectOne(new CatDevOrderResp(result.getPid(), 1, 10), "getOrderCountByPid");
				if (count > 0) {
					history.setLtime(TJKUtils.DateTime());
					history.setIstatus(1);
					catDevZJInviteIncomeHistoryRepository.saveAndFlush(history);
					/* 邀请好友任务完成,记录邀请人的通知缓存中 */
					asyncService.updateCatDevInviteAwardRecord(history.getYid(), 1, history.getIncome(),
							result.getNikename(), history.getItype());
				}
			}
		}

		// 查询连续签到天数
		CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(account);
		result.setSigns(historyResp.getSigns());
		String endDate = historyResp.getEndDate();
		// 如果最后签到的日期不是为今日,则记为今日未签到
		if (endDate == null || !endDate.equals(TJKUtils.DateTime(TJKUtils.YYYY_MM_DD))) {
			// 今天未签到
			result.setSigned(0);
		} else {
			// 如果连续签到天数为0,则说明今日已拒签
			if (historyResp.getSigns() == 0) {
				result.setSigned(-1);
			} else {
				result.setSigned(1);
			}
		}

		// 获取当前签到红包是否领取
		result.setSignedpcks(getSignedReceiveStatus(account) == true ? 1 : 0);

		// 查询现金豆数量与现金红包
		CatDevUserInfoResp beansData = cacheService.getCatDevBeansData(account);
		result.setBeans(beansData.getBeans());
		result.setAbeans(beansData.getAbeans());
		result.setJbeans(beansData.getJbeans());
		result.setBeans(cacheService.getCatDevLastBeans(account));
		result.setRpt(cacheService.getCatDevLastRMB(account));

		// 设置用户昵称
		result.setNikename(AesEncryptUtils.decrypt(account));

		// 判断是否已填写身份证号
		if (result.getIdcard().length() == 18) {
			// 对身份证号进行处理
			result.setIdcard(result.getIdcard().replaceAll("(?<=[\\d]{4})\\d(?=[\\d]{4})", "*"));
		}

		// 查询正在入账金额
		Long amount = longDao.selectOne(new CatDevOrderResp(result.getPid(), 0, 10), "getOrderAmountByStatus");
		result.setRcode(amount);

		// 1.1.6版本查询淘礼金信息
		TLJInfo tljInfo = tljDao.selectOne(new CatDevUserInfo(result.getPid()), "getTljInfo");
		if (tljInfo != null) {
			result.setTljInfo(tljInfo);
		}

		CatDevUserInfoResp.CashBalanceInfo balanceInfo = cacheService.getUserBalance(result.getPid());
		balanceInfo.setReadyRebate(amount);
		result.setBalanceInfo(balanceInfo);

		// 设置奖品碎片信息
		result.setPrizeInfoResp(catGameService.getCVSPrizeInfoResp(account));

		// 设置订单状态
		Integer orderNumber = cacheService.getUserOrderNumber(account);
		CatDevCountResp countResp = new CatDevCountResp();
		// 设置订单数量
		countResp.setOrderRebateCount(orderNumber == null ? 0 : orderNumber);
		result.setOrderStatus(orderNumber == null ? 0 : 1);
		// 获取返利红包总数
		countResp.setRedPacketNum(catDevReRedHistoryRepository.countByPid(account));
		result.setCountResp(countResp);
		// 记录登录IP
		asyncService.insertLoginIp(request, account);

		result.setAdStatus(0);

		// 判断用户是否满足新人提现条件
		result.setNewUserRemit(isAbleNewUserRemit(result.getPid()) ? 1 : 0);
		return result;
	}

	@Override
	public CatDevUserInfo getCatDevUserInfoByUserid(String userid) {
		String userJson = cacheService.getCatDevUserInfoByUserid(userid);
		return StringUtils.isEmpty(userJson) ? null : JSON.parseObject(userJson, CatDevUserInfo.class);
	}

	@Override
	public CatDevUserInfo getCatDevUserInfoByPid(String pid) {
		String userJson = cacheService.getCatDevUserInfoByPid(pid);
		return StringUtils.isEmpty(userJson) ? null : JSON.parseObject(userJson, CatDevUserInfo.class);
	}

	@Override
	public CatDevUserInfo getCatDevUserInfoByPhone(String phone) {
		String userJson = cacheService.getCatDevUserInfoByPhone(phone);
		return StringUtils.isEmpty(userJson) ? null : JSON.parseObject(userJson, CatDevUserInfo.class);
	}

	@Override
	public CatDevUserInfo getCatDevUserInfoByUnionid(String unionid) {
		if (StringUtils.isBlank(unionid) || unionid.length() < 10) {
			return null;
		}
		String userJson = cacheService.getCatDevUserInfoByUnionid(unionid);
		return StringUtils.isEmpty(userJson) ? null : JSON.parseObject(userJson, CatDevUserInfo.class);
	}

	@Override
	public CatDevSignedHistoryResp setSignedDaily(String pid) {
		CatDevSignedHistory signedHistory = signedHistoryRepository.findByPidAndStime(pid, LocalDate.now().toString());
		// 查询今日签到未领取的现金豆的记录
		List<CatDevSignedBeansHistory> list = signedBeansHistoryDao.list(new CatDevSignedBeansHistory(pid),
				"getTodaySignInList");
		// 未查询到有签到现金豆奖励记录
		if (list == null || list.size() < 1) {
			return null;
		}
		if (signedHistory != null) {
			signedHistory.setSignStatus(1);
			signedHistory.setLtime(TJKUtils.DateTime());
			if (signedHistoryRepository.saveAndFlush(signedHistory) == null) {
				return null;
			}
			// 更新中奖状态
			CatDevSignedBeansHistory beansHistory = list.get(0);
			beansHistory.setDstatus(1);
			beansHistory.setLtime(TJKUtils.DateTime());
			signedBeansHistoryRepository.saveAndFlush(beansHistory);

			// 查询连续签到天数
			CatDevSignedHistoryResp historyResp = cacheService.get7SignInNumberDays(pid);
			return historyResp;
		}
		return null;
	}

	@Override
	public Object iosLoginValidate(String pid, Integer rtype, Integer utype, String brand, String model, String vscode,
			String cid, String imei, String imsi, String userid, String identityToken, String authorizationCode,
			Integer pindex) {
		pindex = pindex == null ? 0 : pindex;
		CatDevUserInfo idev = getCatDevUserInfoByUserid(userid);

		/* 苹果用户存在，直接返回用户信息 */
		if (idev != null) {
			return info(1, idev, pindex, vscode, cid);
		}

		/* 同手机微信已经登录过，手动绑定苹果账户的userid */
		if (StringUtils.isNotBlank(pid)) {
			/* 苹果用户不存在，绑定 */
			CatDevUserInfo dev = getCatDevUserInfoByPid(pid);
			if (dev != null && (dev.getUserid() == null || dev.getUserid().length() < 30)) {
				dev.setUserid(userid);
				if (catDevUserInfoRepository.saveAndFlush(dev) != null) {
					return info(1, dev, pindex, vscode, cid);
				}
			}
		}

		AppleAPI apple = AppleAPI.getInstance(utype);
		String keyStr = cacheService.getAppleKeys();
		Map<String, String> keys = apple.getAppleKeys(keyStr);
		if (apple.validateIphone(keys, identityToken, userid) == 1) {
//			/* 保存用户验证记录，登录注册时进行验证 */
//			String key = "CAT_IOS_USER_VALIDATE_INFO", hashKey = userid;
//			redis1.opsForHash().put(key, hashKey, TJKUtils.DateTime());
//			return 1;

			/* 认证成功，去注册 */
			String openid = "-";
			String nickname = "默认昵称";
			int sex = 0;
			String headimgurl = "https://img.jiuqumao.cn/imgs/193ca7be028d581d7fce08ace380f26a.png";
			String unionid = "";
			CatDevWeInfo weInfo = new CatDevWeInfo(openid, nickname, sex, headimgurl, unionid);
			return login(userid, rtype, weInfo, vscode, brand, model, cid, imei, imsi, pindex);
		}
		return null;
	}

	@Override
	public UserTaskData getTaskReward(Integer rtype, CatDevUserTaskRecord taskRecord) {
		// 获取任务次数
		CatDevUserTaskConfig taskConfig = catDevUserTaskConfigRepository.findByTypeId(taskRecord.getTaskType());
		taskRecord.setTaskNum(taskRecord.getTaskNum() + 1);
		if (taskConfig.getTaskNum() <= taskRecord.getTaskNum()) {
			taskRecord.setTaskStatus(1);
			taskRecord.setReceiveStatus(1);
		}
		taskRecord.setLtime(TJKUtils.DateTime());
		if (newUserTaskRecordRepository.saveAndFlush(taskRecord) == null) {
			return null;
		}
		// 如果为观看视频广告
		if (taskRecord.getTaskType() == 4) {
			getBeansByVideo(rtype, taskRecord.getPid(), 0);
		}
		UserTaskData data = new UserTaskData();
		BeanUtils.copyProperties(taskRecord, data);
		data.setReceiveStatus(2);
		data.setTaskContent(taskConfig.getContent());
		return data;
	}

	@Override
	public CatDevRemitRecordResp beanRemit(Integer rtype, Integer appId, String pid, long tmoney, long convertBean,
			int mode) {
		// 如果需转换现金豆大于0，则进行转换
		if (convertBean > 0) {
			boolean convert = beansConvert(rtype, pid, convertBean);
			if (!convert) {
				return null;
			}
		} else {
			return null;
		}
		// 进行提现
		return remit(rtype, appId, pid, 0, mode, "", "", tmoney);
	}

	@Override
	public String commitFeedback(Integer rtype, Integer appId, String brand, String model, String vscode, Integer type,
			String questionDesc, String questionPic, String userID) {
		CatUserFeedbackHistory history = new CatUserFeedbackHistory(userID, appId, rtype, brand, model, vscode, type,
				questionDesc, questionPic, new Date());
		if (userFeedbackHistoryRepository.save(history) == null) {
			return null;
		}
		return "success";
	}

	@Override
	public List<CatUserFeedbackHistoryResp> getFeedbackHistory(Integer rtype, Integer appId, String userid) {
		List<CatUserFeedbackHistory> list = userFeedbackHistoryRepository
				.findByUserIdAndAppIdOrderByCreateTimeDesc(userid, appId);
		if (list == null) {
			return null;
		}
		List<CatUserFeedbackHistoryResp> list2 = JSON.parseArray(JSON.toJSONString(list),
				CatUserFeedbackHistoryResp.class);

		// 异步保存已回复的数据
		asyncService.updateFeedbackHistory(appId, userid);
		return list2;
	}

	@Override
	public String saveDeviceToken(Integer rtype, String pid, String devicetoken, String deviceid) {
		// TODO Auto-generated method stub
		int idType = 0;
		// 判断pid是否为空，为空的话就取设备id
		if (StringUtils.isEmpty(pid)) {
			pid = deviceid;
			idType = 1;
		}

		// 判断当设备值已存在且id为设备id时，更新设备id为用户id
		List<CatDevDeviceToken> result = catDevDeviceTokenRepository.findByDeviceTokenOrPid(devicetoken, pid);
		// 1.判断同一用户登录不同设备有多条记录时
		if (result != null && result.size() > 1) {
			// 判断登录账户为同一账户时，设备更新
			if (result.get(0).getPid().equals(pid)) {
				catDevDeviceTokenRepository.delete(result.get(1));
				result.get(0).setDeviceToken(devicetoken);
				result.get(0).setUpdateTime(new Date());
				catDevDeviceTokenRepository.saveAndFlush(result.get(0));
			} else {
				catDevDeviceTokenRepository.delete(result.get(0));
				result.get(1).setDeviceToken(devicetoken);
				result.get(1).setUpdateTime(new Date());
				catDevDeviceTokenRepository.saveAndFlush(result.get(1));
			}
		} else if (result == null || result.size() == 0) {
			// 2.当用户id和设备都为null时
			CatDevDeviceToken catDevDeviceToken = new CatDevDeviceToken(pid, devicetoken, idType, new Date(),
					new Date());
			if (catDevDeviceTokenRepository.saveAndFlush(catDevDeviceToken) == null) {
				return null;
			}
		} else {
			// 3.当存在一条记录的时候
			// 判断用户id和保存的id不相等时，保存设备id
			if (!result.get(0).getPid().equals(pid)) {
				result.get(0).setPid(pid);
				result.get(0).setIdType(0);
				catDevDeviceTokenRepository.saveAndFlush(result.get(0));
			}
		}
		return "success";
	}

	/**
	 * 获取用户财务状态
	 * 
	 * @param pid
	 * @return
	 */
	@Override
	public int getCatDevUserFstatus(String pid) {
		int result = 0;
		CatDevUserInfoResp user = cacheService.getCatDevUserLoginInfo(pid);
		if (user != null) {
			result = user.getFstatus();
		}
		return result;
	}

}
